#include <Syscall.h>
#include <linux/types.h>
#include <linux/sockios.h>
#include <linux/unistd.h>
#include <linux/net.h>
#include "Network.h"

/// <summary>
/// The CreateSocket function
/// creates a socket that is bound
/// to a specific transport-service provider.
/// </summary>
int CreateSocket(int family, int type, int protocol)
{
	int handle = 0;
	unsigned long data[3];
	data[0] = family;
	data[1] = type;
	data[2] = protocol;

	if ((handle = Syscall2(__NR_socketcall, SYS_SOCKET, (int)data)) < 0)
		return -1;

	return handle;
}

/// <summary>
/// The Connect function
/// establishes a connection
/// to a specified socket.
/// </summary>
int Connect(int socket)
{
	unsigned long data[3];
	data[0] = socket;
	//args[1] = (unsigned long)saddr;
	//args[2] = addrlen;

	if (Syscall2(__NR_socketcall, SYS_CONNECT, (int)data) < 0)
		return -1;

	return 0;
}

/// <summary>
/// The Bind function
/// associates a local address with a socket.
/// </summary>
int NetBind(int socket, const struct sockaddr *addr, int addrlen)
{
	unsigned long data[3];
	data[0] = socket;
	data[1] = (unsigned long)addr;
	data[2] = addrlen;

	if (Syscall2(__NR_socketcall, SYS_BIND, (int)data) < 0)
		return -1;

	return 0;
}

/// <summary>
/// The Send function
/// sends data on a connected socket.
/// </summary>
int NetSend(int socket, const void *buffer, int len, int flags)
{
	int bytes = 0;
	unsigned long data[4];
	data[0] = socket;
	data[1] = (unsigned long)buffer;
	data[2] = len;
	data[3] = flags;

	if ((bytes = Syscall2(__NR_socketcall, SYS_SEND, (int)data)) < 0)
		return -1;

	return bytes;
}

/// <summary>
/// The Send function
/// sends data on a connected socket.
/// </summary>
int NetSendTo(int socket, const void *buffer, int len, int flags, const struct sockaddr *to, int tolen)
{
	int bytes = 0;
	unsigned long data[6];
	data[0] = socket;
	data[1] = (unsigned long)buffer;
	data[2] = len;
	data[3] = flags;
	data[4] = (unsigned long)to;
	data[5] = tolen;

	if ((bytes = Syscall2(__NR_socketcall, SYS_SENDTO, (int)data)) < 0)
		return -1;

	return bytes;
}

/// <summary>
/// The CloseSocket function
/// closes an existing socket.
/// </summary>
int CloseSocket(int handle)
{
	int result = -1;
	if ((result = Syscall1(__NR_close, handle)) < 0)
		return -1;
	return result;
}
